package cn.agiledata.bank.transaction.audit.service;

import java.util.ArrayList;
import java.util.List;

import cn.agiledata.bank.audit.dao.IAuditOperandTypeDao;
import cn.agiledata.bank.audit.exception.AuditException;
import cn.agiledata.bank.audit.form.AuditRuleForm;
import cn.agiledata.bank.audit.form.StepBean;
import cn.agiledata.bank.audit.service.AuditGroupService;
import cn.agiledata.bank.audit.service.AuditRuleService;
import cn.agiledata.bank.audit.service.AuditStepService;
import cn.agiledata.bank.common.dao.OperatorDao;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.hibernateBean.AuditGroup;
import cn.agiledata.bank.hibernateBean.AuditOperandType;
import cn.agiledata.bank.hibernateBean.AuditRule;
import cn.agiledata.bank.hibernateBean.AuditStep;
import cn.agiledata.bank.hibernateBean.Operator;

public class CompanyAuditServiceImpl implements CompanyAuditService {

    private OperatorDao operatorDao;

    private IAuditOperandTypeDao auditOperandTypeDao;

    private AuditGroupService auditGroupService;

    private AuditStepService auditStepService;

    private AuditRuleService auditRuleService;

    public void setOperatorDao(OperatorDao operatorDao) {
        this.operatorDao = operatorDao;
    }

    public void setAuditGroupService(AuditGroupService auditGroupService) {
        this.auditGroupService = auditGroupService;
    }

    public void setAuditStepService(AuditStepService auditStepService) {
        this.auditStepService = auditStepService;
    }

    public CompanyAuditServiceImpl() {
    }

    public void setAuditOperandTypeDao(IAuditOperandTypeDao auditOperandTypeDao) {
        this.auditOperandTypeDao = auditOperandTypeDao;
    }

    public void setAuditRuleService(AuditRuleService auditRuleService) {
        this.auditRuleService = auditRuleService;
    }

    public List getInitAuditSteps(Long id) {
        int size = this.operatorDao.getAuditList(id).size();
        if (size > 6)
            size = 6;
        ArrayList list = new ArrayList();


        for (int i = 0; i < size; i++) {

            StepBean bean = new StepBean();
            String name = getStepName(i);
            bean.setId(i);
            bean.setName(name);
            list.add(bean);
        }

        return list;
    }

    public String getStepName(int i) {
        String name = new String();
        switch (i) {
        case 0:
            name = Constant.AUDIT_ONE_STEPS;
            break;
        case 1:
            name = Constant.AUDIT_TWO_STEPS;
            break;
        case 2:
            name = Constant.AUDIT_THREE_STEPS;
            break;
        case 3:
            name = Constant.AUDIT_FOUR_STEPS;
            break;
        case 4:
            name = Constant.AUDIT_FIVE_STEPS;
            break;
        case 5:
            name = Constant.AUDIT_SIX_STEPS;
        }
        return name;
    }

    public AuditRule[] getEnabledUserAuditRuleList(long accountId) {
        return this.auditRuleService.getUserAuditRuleList(accountId, true);
    }

    public AuditOperandType getAuditOperandTypeById(Long id) {
        return this.auditOperandTypeDao.getAuditOperandTypeById(id.longValue());
    }

    public void saveOrUpdateAuditRule(AuditRuleForm form, int size,
            Operator oper, String name, long auditOperandTypeId)
            throws AuditException {
        String[] operId;
        String groupName = name;
        AuditStep[] step = null;
        AuditRule rule = new AuditRule();
        ArrayList opers = new ArrayList();
        for (int i = 0; i < size; i++) {

            switch (i) {
            case 0:
                operId = form.getAuditGroupBeanList0();
                break;
            case 1:
                operId = form.getAuditGroupBeanList1();
                break;
            case 2:
                operId = form.getAuditGroupBeanList2();
                break;
            case 3:
                operId = form.getAuditGroupBeanList3();
                break;
            case 4:
                operId = form.getAuditGroupBeanList4();
                break;
            default:
                operId = form.getAuditGroupBeanList5();
            }
            if (operId == null)
                throw AuditException.AUDIT_RULE_NOT_VALID;
            int length = operId.length;
            if (length == 0)
                throw AuditException.AUDIT_RULE_NOT_VALID;
            long[] auditors = new long[length];

            for (int a = 0; a < length; a++) {
                long auditor = new Long(operId[a]).longValue();
                auditors[a] = auditor;
                if (opers.contains(operId[a]))
                    throw AuditException.AUDIT_RULE_NOT_VALID_TOO_MANY;
                opers.add(operId[a]);
            }
            AuditGroup group = auditGroupService.addUserAuditGroup(oper,
                    groupName, null, auditors);
            String stepName = getAuditStepName(name, size, i);
            step = auditStepService.appendAuditStep(oper.getId(), stepName,
                    group, step);
        }

        rule = auditRuleService.addUserAuditRule(oper, auditOperandTypeId,
                groupName, 1, step);
    }

    public String getAuditStepName(String name, int size, int i) {

        switch (i) {
        case 0:
            if (size < 2)
                name = name + Constant.AUDIT_FINAL_STEP;
            else
                name = name + Constant.AUDIT_FIRST_STEP;
            break;
        case 1:
            if (size == 2)
                name = name + Constant.AUDIT_FINAL_STEP;
            else
                name = name + Constant.AUDIT_SECOND_STEP;
            break;
        case 2:
            if (size == 3)
                name = name + Constant.AUDIT_FINAL_STEP;
            else
                name = name + Constant.AUDIT_THIRD_STEP;
            break;
        case 3:
            if (size == 4)
                name = name + Constant.AUDIT_FINAL_STEP;
            else
                name = name + Constant.AUDIT_FORTH_STEP;
            break;
        case 4:
            if (size == 4)
                name = name + Constant.AUDIT_FINAL_STEP;
            else
                name = name + Constant.AUDIT_FIFTH_STEP;
            break;
        case 5:
            name = name + Constant.AUDIT_FINAL_STEP;
        }

        return name;
    }

}
